Skip to content

feat: let attenuate_grid_peaks withhold charging (#71)#79

Open
andig wants to merge 1 commit into
mainfrom
feat/71-attenuate-grid-peaks-withhold-charge
Open

feat: let attenuate_grid_peaks withhold charging (#71)#79
andig wants to merge 1 commit into
mainfrom
feat/71-attenuate-grid-peaks-withhold-charge

Conversation

@andig

@andig andig commented Jun 13, 2026

Copy link
Copy Markdown
Member

closes #71

The attenuate_grid_peaks charging strategy could previously only re-time charging toward high-solar intervals, never forgo it. For feed-in peak shaving (Solarspitzengesetz) the battery should also be able to hold off charging early in the day, so feed-in spreads out and capacity stays free to absorb the midday peak that would otherwise be lost to the export cap. Whether the optimizer may plan this depends on the battery being able to pause charging (the counterpart to evcc-io/evcc#27906), so it is gated behind a new per-battery capability.

  • New per-battery withhold_charge flag (default false), behavior unchanged when unset
  • Under attenuate_grid_peaks, a withhold_charge battery gets a net-negative incentive on charging below the solar peak, so it may forgo charging and export cost-neutral surplus instead of filling early
  • The incentive stays in the cost-neutral tie-breaker layer, so the economic optimum is unaffected
  • Added tests covering the defer versus withhold behavior and cost-neutrality

The attenuate_grid_peaks charging strategy previously only re-timed
(deferred) battery charging toward high-solar intervals via a +c*ft
reward. For feed-in peak shaving (Solarspitzengesetz) it is also useful
to actively withhold charging below the solar peak, keeping battery
capacity free to absorb the midday peak instead of filling early and
losing curtailed surplus.

Add a per-battery `withhold_charge` capability flag. When set, the
strategy adds a -c*(max_solar-ft) term so charging below the peak
carries a net-negative incentive, letting the battery forgo charging
(exporting cost-neutral surplus) rather than only deferring it. This
mirrors a battery that can be told to pause charging (evcc#27906);
without the capability the strategy behaviour is unchanged.

Stays within the cost-neutral tie-breaker regime: the term is not part
of get_clean_objective_value(), so the economic optimum is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
iseeberg79 added a commit to iseeberg79/evcc that referenced this pull request Jun 26, 2026
Adds an experimental battery HoldCharge mode driven by the optimizer
plan. When enabled, the battery's charging is limited to the optimizer's
planned per-slot power (read from the per-battery suggestion), so it can
withhold charging early and absorb the midday feed-in peak while keeping
discharge available. Builds on the optimizer suggestion (evcc-io/evcc
evcc-io#30834) and the withhold_charge capability (evcc-io/optimizer#79).

- setting batteryAutoHoldCharge: key, field, Get/Set + site.API, HTTP
  route, persist/publish/restore
- optimizer request: set the battery WithholdCharge flag
- battery mode: require BatteryHoldCharge while enabled (discharge stays
  allowed); the meter template applies the planned limit per slot
- kostal-plenticore-gen2: holdcharge case reads the suggestion via the
  state source (jq) and writes it to the charge-power-limit register;
  new batteryIndex param for multi-battery setups
- UI: experimental HoldCharge toggle in battery settings + en/de texts

TEMP: go.mod replaces the optimizer with the local fork (evcc-io#79); remove
before merge once the optimizer release with withhold_charge is bumped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
iseeberg79 added a commit to iseeberg79/evcc that referenced this pull request Jun 27, 2026
Adds an experimental battery HoldCharge mode driven by the optimizer
plan. When enabled, the battery's charging is limited to the optimizer's
planned per-slot power (read from the per-battery suggestion), so it can
withhold charging early and absorb the midday feed-in peak while keeping
discharge available. Builds on the optimizer suggestion (evcc-io/evcc
evcc-io#30834) and the withhold_charge capability (evcc-io/optimizer#79).

- setting batteryAutoHoldCharge: key, field, Get/Set + site.API, HTTP
  route, persist/publish/restore
- optimizer request: set the battery WithholdCharge flag
- battery mode: require BatteryHoldCharge while enabled (discharge stays
  allowed); the meter template applies the planned limit per slot
- kostal-plenticore-gen2: holdcharge case reads the suggestion via the
  state source (jq) and writes it to the charge-power-limit register;
  new batteryIndex param for multi-battery setups
- UI: experimental HoldCharge toggle in battery settings + en/de texts

TEMP: go.mod replaces the optimizer with the local fork (evcc-io#79); remove
before merge once the optimizer release with withhold_charge is bumped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add feed-in peak shaving, i.e. Solarspitzengesetz (Solar Peak Act)

1 participant